<template>
  <dialog ref="dialogRef" class="package-method-dialog" @close="emit('close')">
    <form method="dialog" class="dialog-body" @submit.prevent="save">
      <header class="dialog-header">
        <h3>{{ current?.id ? '编辑包装方式' : '新建包装方式' }}</h3>
        <button type="button" class="ui-close-btn" @click="close" aria-label="关闭">
          <svg viewBox="0 0 24 24" class="icon-x" fill="none" stroke="currentColor" stroke-width="2">
            <line x1="18" y1="6" x2="6" y2="18" />
            <line x1="6" y1="6" x2="18" y2="18" />
          </svg>
        </button>
      </header>

      <section class="dialog-content">
        <!-- 基础信息 -->
        <div class="section-card">
          <h4 class="section-title">基础信息</h4>
          <div class="form-grid">
            <label class="field-label">
              包装方式名称
              <input v-model="form.name" placeholder="例如：标准纸箱包装" required />
            </label>
            <label class="field-label">
              状态
              <select v-model="form.status" required>
                <option value="enabled">启用</option>
                <option value="disabled">废弃</option>
              </select>
            </label>
          </div>
        </div>

        <!-- BOM 明细 -->
        <div class="section-card">
          <div class="section-header">
            <h4 class="section-title">包装BOM明细</h4>
            <div class="section-actions">
              <button type="button" class="btn secondary sm" @click="openAddBom">
                <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2">
                  <line x1="12" y1="5" x2="12" y2="19" />
                  <line x1="5" y1="12" x2="19" y2="12" />
                </svg>
                新增BOM行
              </button>
              <button type="button" class="btn secondary sm" @click="openImportBom">
                <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2">
                  <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
                  <polyline points="7 10 12 15 17 10" />
                  <line x1="12" y1="15" x2="12" y2="3" />
                </svg>
                导入BOM行
              </button>
            </div>
          </div>

          <div class="bom-table-wrapper unified" v-if="form.bomItems.length">
            <table class="entry-table fancy">
              <thead>
                <tr>
                  <th style="width: 60px">类型</th>
                  <th style="width: 80px">编码</th>
                  <th style="width: 140px">名称</th>
                  <th style="width: 120px">物料分类</th>
                  <th style="width: 60px">规格</th>
                  <th style="width: 80px">费用模式</th>
                  <th style="width: 100px">金额/单价(¥)</th>
                  <th style="width: 80px">数量</th>
                  <th style="width: 100px">行成本(¥)</th>
                  <th style="width: 70px">操作</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(r, idx) in form.bomItems" :key="r._localId || r.id || idx">
                  <td class="type-cell">{{ r.type==='production' ? '物料' : '包装' }}</td>
                  <td>{{ r.materialCode || '-' }}</td>
                  <td class="strong">{{ r.costName || r.materialName }}</td>
                  <td class="category-cell">{{ r.category || '-' }}</td>
                  <td class="spec-cell" :title="r.spec">{{ r.spec || '-' }}</td>
                  <td class="fee-mode">{{ r.feeDetail ? (r.feeDetail.mode==='fixed' ? '固定' : '计数') : '-' }}</td>
                  <td class="fee-amount">{{ r.feeDetail ? r.feeDetail.amount.toFixed(2) : (r.unitCost||0).toFixed(2) }}</td>
                  <td class="qty">
                    <template v-if="r.feeDetail && r.feeDetail.mode==='count'">
                      <input type="number" class="qty-input" v-model.number="r.feeDetail.quantity" min="1" step="1" @blur="ensureQty(r)" />
                    </template>
                    <template v-else>-</template>
                  </td>
                  <td class="line-cost">{{ lineCost(r).toFixed(2) }}</td>
                  <td class="actions">
                    <button type="button" class="link-btn" @click="editBomItem(idx)">编辑</button>
                    <button type="button" class="link-btn danger" @click="removeBomItem(idx)">删除</button>
                  </td>
                </tr>
              </tbody>
              <tfoot>
                <tr><td colspan="8" class="tar">合计</td><td class="line-cost">{{ bomTotal.toFixed(2) }}</td><td></td></tr>
              </tfoot>
            </table>
          </div>
          <p v-else class="empty-hint">暂无BOM行，请新增或导入。</p>
        </div>
      </section>

      <footer class="dialog-actions">
        <button type="button" class="btn secondary" @click="close">取消</button>
        <button type="submit" class="btn primary">保存</button>
      </footer>
    </form>

    <!-- BOM 行编辑对话框 -->
    <BomSimpleEntryDialog
      ref="bomEntryDialogRef"
      :duplicate-graceful="true"
      preset-bom-type="package"
      preset-product-type="通用"
      :lock-bom-type="true"
      :lock-product-type="true"
      @save="handleBomSave"
      @request-attr-edit="handleAttrEdit"
      @request-attr-view="handleAttrView"
    />

    <!-- BOM 行导入对话框 -->
    <BomLineImportDialog ref="bomImportDialogRef" @import="handleBomImport" />

    <!-- 属性编辑对话框 -->
  <DynamicAttributeDialog ref="attrDialogRef" />

    <!-- 属性查看对话框 -->
    <AttributeViewer ref="attrViewerRef" />

    <!-- 费用查看对话框 -->
    <SimpleCostModeViewer ref="feeViewerRef" />
  </dialog>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import BomSimpleEntryDialog from '../../bomSimple/components/BomSimpleEntryDialog.vue';
import BomLineImportDialog from '../../sku/components/BomLineImportDialog.vue';
import DynamicAttributeDialog from '../../bomSimple/components/DynamicAttributeDialog.vue';
import AttributeViewer from '../../bomSimple/components/AttributeViewer.vue';
import SimpleCostModeViewer from '../../bomSimple/components/SimpleCostModeViewer.vue';

interface BomItem {
  id?: string;
  _localId?: string;
  seq: number;
  type: 'production' | 'packaging';
  materialCode: string;
  materialName: string;
  costName: string;
  category: string;
  materialCategory?: string; // 分类 ID（字符串形式）
  classId?: number | string; // 分类 ID（后端 classId）
  spec: string;
  qty: number;
  unit: string;
  lossFactor: number;
  unitCost: number;
  attributes: Record<string, any>;
  attributeDefinitions?: any[];
  attributeValues?: Record<string, any>;
  feeDetail?: {
    mode: 'fixed' | 'count';
    amount: number;
    quantity?: number;
  };
}

interface PackageMethod {
  id?: string;
  name: string;
  pic?: string;
  bomItems: BomItem[];
  status?: 'enabled' | 'disabled';
}

const emit = defineEmits<{
  (e: 'save', payload: PackageMethod): void;
  (e: 'close'): void;
}>();

const dialogRef = ref<HTMLDialogElement | null>(null);
const current = ref<PackageMethod | null>(null);
const form = ref<PackageMethod>({
  name: '',
  bomItems: []
});

const bomEntryDialogRef = ref<InstanceType<typeof BomSimpleEntryDialog> | null>(null);
const bomImportDialogRef = ref<InstanceType<typeof BomLineImportDialog> | null>(null);
const attrDialogRef = ref<InstanceType<typeof DynamicAttributeDialog> | null>(null);
const attrViewerRef = ref<InstanceType<typeof AttributeViewer> | null>(null);
const feeViewerRef = ref<InstanceType<typeof SimpleCostModeViewer> | null>(null);

const currentEditingBomIndex = ref<number>(-1);

function open(pkg?: PackageMethod) {
  if (pkg) {
    current.value = pkg;
    form.value = {
      id: pkg.id,
      name: pkg.name,
      pic: pkg.pic,
      status: pkg.status || 'enabled',
      bomItems: JSON.parse(JSON.stringify(pkg.bomItems || []))
    };
  } else {
    current.value = null;
    form.value = {
      name: '',
      pic: '',
      status: 'enabled',
      bomItems: []
    };
  }
  dialogRef.value?.showModal();
}

function close() {
  dialogRef.value?.close();
}

function save() {
  if (!form.value.name.trim()) {
    alert('请输入包装方式名称');
    return;
  }

  emit('save', {
    id: form.value.id,
    name: form.value.name,
    pic: form.value.pic,
    bomItems: form.value.bomItems,
    status: form.value.status || 'enabled'
  });
  close();
}

// BOM 行管理
function openAddBom() {
  currentEditingBomIndex.value = -1;
  // 使用新增模式（不传 row），由 BomSimpleEntryDialog 预设并锁定 bomType=package & productType=通用
  bomEntryDialogRef.value?.open();
}

function editBomItem(index: number) {
  currentEditingBomIndex.value = index;
  const item = form.value.bomItems[index];
  
  // 转换为 BomSimpleEntryDialog 需要的格式
  const entryData = {
    id: item.id,
    classId: item.classId,
    costName: item.costName,
    bomType: (item.type === 'packaging' ? 'package' : 'product') as 'package' | 'product',
    productType: '通用',
    materialCode: item.materialCode,
    materialCategory: item.materialCategory,
    costMode: (item.feeDetail?.mode || 'fixed') as 'fixed' | 'count',
    fixedAmount: item.feeDetail?.mode === 'fixed' ? item.feeDetail.amount : undefined,
    unitPrice: item.feeDetail?.mode === 'count' ? item.feeDetail.amount : undefined,
    attributeSpec: item.spec || '',
    attributeDefinitions: item.attributeDefinitions || [],
    attributeValues: item.attributeValues || {}
  };
  
  bomEntryDialogRef.value?.open(entryData as any);
}

function removeBomItem(index: number) {
  if (confirm('确定要删除此BOM行吗？')) {
    form.value.bomItems.splice(index, 1);
  }
}

function handleBomSave(payload: any) {
  if (!payload) return;
  
  // 验证必要字段：确保名称已生成（如果是新增且名称为空，说明属性设置有问题）
  if (!payload.costName || !payload.costName.trim()) {
    console.error('BOM 行保存失败：名称为空', payload);
    alert('保存失败：BOM 行名称未能生成，请确保已正确设置物料分类和属性。');
    return;
  }
  
  // 参考产品页面逻辑：判断是编辑还是新增
  let existingIdx = -1;
  if (currentEditingBomIndex.value >= 0) {
    existingIdx = currentEditingBomIndex.value;
  } else if (payload.id) {
    existingIdx = form.value.bomItems.findIndex(r => r.id === payload.id);
  } else {
    // 按名称+分类查找是否已存在
    existingIdx = form.value.bomItems.findIndex(r => 
      r.costName === payload.costName && r.materialCategory === payload.materialCategory
    );
  }
  
  const isEdit = existingIdx >= 0;
  
  if (isEdit) {
    // 编辑现有行
    const target = form.value.bomItems[existingIdx];
    form.value.bomItems[existingIdx] = {
      ...target,
      costName: payload.costName,
      materialCode: payload.materialCode || target.materialCode,
      materialName: payload.costName,
      category: payload.className || target.category,
      materialCategory: payload.materialCategory || target.materialCategory,
      classId: payload.classId !== undefined ? payload.classId : target.classId,
      spec: payload.attributeSpec || payload.spec || target.spec,
      attributeDefinitions: payload.attributeDefinitions || target.attributeDefinitions,
      attributeValues: payload.attributeValues || target.attributeValues,
      feeDetail: payload.costMode === 'fixed'
        ? { mode: 'fixed', amount: payload.fixedAmount ?? 0 }
        : { mode: 'count', amount: payload.unitPrice ?? 0, quantity: target.feeDetail?.quantity || 1 }
    };
  } else {
    // 新增行
    const bomItem: BomItem = {
      id: payload.id || '',
      _localId: payload._localId || `local-${Date.now()}-${Math.random()}`,
      seq: form.value.bomItems.length + 1,
      type: payload.bomType === 'package' ? 'packaging' : 'production',
      materialCode: payload.materialCode || '',
      materialName: payload.costName || '',
      costName: payload.costName || '',
      category: payload.className || '', // 从 BomSimpleEntryDialog 返回的 className
      materialCategory: payload.materialCategory || '', // 分类代码/ID
      classId: payload.classId || undefined,
      spec: payload.attributeSpec || payload.spec || '',
      qty: payload.qty || 1,
      unit: payload.unit || 'pcs',
      lossFactor: payload.lossFactor || 1,
      unitCost: payload.unitCost || 0,
      attributes: payload.attributeValues || {},
      attributeDefinitions: payload.attributeDefinitions || [],
      attributeValues: payload.attributeValues || {},
      feeDetail: payload.costMode === 'fixed'
        ? { mode: 'fixed', amount: payload.fixedAmount ?? payload.unitPrice ?? 0 }
        : { mode: 'count', amount: payload.unitPrice ?? payload.fixedAmount ?? 0, quantity: 1 }
    };
    
    // 处理重复名称情况
    if (payload.__duplicateName) {
      const exist = form.value.bomItems.find(r => r.costName === bomItem.costName);
      if (!exist) {
        form.value.bomItems.push(bomItem);
      }
    } else {
      form.value.bomItems.push(bomItem);
    }
  }
  
  currentEditingBomIndex.value = -1;
}

function openImportBom() {
  bomImportDialogRef.value?.open();
}

function handleBomImport(lines: any[]) {
  const existingNameSet = new Set(form.value.bomItems.map(l => l.costName || l.materialName));
  lines.forEach(line => {
    const name = line.costName || line.materialName;
    if(existingNameSet.has(name)) return; // 跳过重复（基于名称）
    const bomItem: BomItem = {
      id: line.id || '',
      _localId: line._localId || `import-${Date.now()}-${Math.random()}`,
      seq: form.value.bomItems.length + 1,
      type: line.type,
      materialCode: line.materialCode || '',
      materialName: line.materialName || '',
      costName: line.costName || '',
      category: line.category || '',
      materialCategory: line.materialCategory || '',
      classId: line.classId || undefined,
      spec: line.spec || '',
      qty: line.qty || 1,
      unit: line.unit || 'pcs',
      lossFactor: line.lossFactor || 1,
      unitCost: line.unitCost || 0,
      attributes: line.attributes || {},
      attributeDefinitions: line.attributeDefinitions || [],
      attributeValues: line.attributeValues || {},
      feeDetail: line.feeDetail
    };
    form.value.bomItems.push(bomItem);
  });
}

// 属性相关
function viewAttr(item: BomItem) {
  const payload = {
    id: item.id || item._localId || 'temp',
    attributeDefinitions: item.attributeDefinitions || [],
    attributeValues: item.attributeValues || {}
  };
  attrViewerRef.value?.open(payload);
}

async function handleAttrEdit(payload: any) {
  if (!payload) return;
  try {
    const result = await attrDialogRef.value?.open({
      categoryCode: payload.categoryCode,
      categoryName: payload.materialName,
      definitions: payload.definitions,
      values: payload.values,
      materialName: payload.materialName
    } as any);
    if (!result) return;
    bomEntryDialogRef.value?.updateAttributes(result.values, result.spec);
  } catch (error) {
    console.error('属性设置失败', error);
  }
}

function handleAttrView(payload: any) {
  attrViewerRef.value?.open({
    id: 'view',
    attributeDefinitions: payload.definitions || [],
    attributeValues: payload.values || {}
  });
}

// 统一行成本计算：feeDetail.fixed -> amount；feeDetail.count -> amount * quantity；否则 unitCost * qty * lossFactor
function lineCost(r: BomItem) {
  if (r.feeDetail) {
    if (r.feeDetail.mode === 'fixed') return r.feeDetail.amount || 0;
    const qty = r.feeDetail.quantity ?? r.qty;
    return (r.feeDetail.amount || 0) * (qty || 1);
  }
  return (r.unitCost || 0) * r.qty * (r.lossFactor || 1);
}

function ensureQty(r: BomItem) {
  if (!(r.feeDetail && r.feeDetail.mode === 'count')) return;
  let q = Number(r.feeDetail.quantity);
  if (!q || q < 1) q = 1;
  r.feeDetail.quantity = Math.round(q);
}

const bomTotal = computed(() => form.value.bomItems.reduce((s, r) => s + lineCost(r), 0));

// 费用相关
function viewFee(item: BomItem) {
  if (!item.feeDetail) return;
  feeViewerRef.value?.open({
    id: item.id || item._localId,
    costMode: item.feeDetail.mode,
    fixedAmount: item.feeDetail.mode === 'fixed' ? item.feeDetail.amount : undefined,
    unitPrice: item.feeDetail.mode === 'count' ? item.feeDetail.amount : undefined
  } as any);
}

defineExpose({ open, close });
</script>

<style scoped>
.package-method-dialog {
  border: none;
  padding: 0;
  border-radius: 20px;
  width: 1200px;
  max-width: 95vw;
  max-height: 90vh;
  box-shadow: 0 14px 38px -10px rgba(15, 23, 42, 0.35), 0 6px 18px -6px rgba(15, 23, 42, 0.25);
}

.package-method-dialog::backdrop {
  background: rgba(15, 23, 42, 0.55);
  backdrop-filter: blur(6px);
}

.dialog-body {
  display: flex;
  flex-direction: column;
  max-height: 90vh;
  background: linear-gradient(145deg, #ffffff, #f8fafc 60%, #f1f5f9);
}

.dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 1.3rem 0.85rem;
  border-bottom: 1px solid #e2e8f0;
}

.dialog-header h3 {
  margin: 0;
  font-size: 19px;
  font-weight: 700;
}

.ui-close-btn {
  background: none;
  border: 1px solid transparent;
  cursor: pointer;
  padding: 0.45rem;
  border-radius: 12px;
  color: #64748b;
  transition: all 0.3s;
}

.ui-close-btn:hover {
  background: linear-gradient(135deg, #fee2e2, #fecaca);
  color: #dc2626;
  transform: rotate(90deg);
}

.icon-x {
  width: 20px;
  height: 20px;
}

.dialog-content {
  flex: 1;
  overflow-y: auto;
  padding: 1.1rem 1.3rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
}

.section-card {
  border: 1px solid #e2e8f0;
  background: linear-gradient(135deg, #ffffff, #f8fafc);
  border-radius: 16px;
  padding: 1rem 1.15rem 1.2rem;
  box-shadow: 0 6px 18px -6px rgba(15, 23, 42, 0.14), 0 2px 6px -2px rgba(15, 23, 42, 0.08);
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.9rem;
}

.section-title {
  margin: 0 0 0.9rem;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.02em;
  position: relative;
  padding-left: 0.75rem;
}

.section-title::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 70%;
  background: linear-gradient(135deg, #3b82f6, #8b5cf6);
  border-radius: 2px;
}

.section-actions {
  display: flex;
  gap: 0.5rem;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1rem;
}

.field-label {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  font-size: 13px;
  font-weight: 600;
  color: #374151;
}

.field-label input {
  padding: 0.7rem 0.85rem;
  border: 1px solid #d1d5db;
  border-radius: 12px;
  font-size: 14px;
  background: #fff;
  transition: all 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  font-weight: 500;
}

.field-label select {
  padding: 0.7rem 0.85rem;
  border: 1px solid #d1d5db;
  border-radius: 12px;
  font-size: 14px;
  background: #fff;
  transition: all 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  font-weight: 500;
  color: #374151;
  cursor: pointer;
}

.field-label input:focus,
.field-label select:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

/* 统一后的 BOM 行表格样式（参照 PackageBomViewDialog entry-table fancy） */
.bom-table-wrapper.unified { 
  border: 1px solid #e2e8f0;
  border-radius: 16px;
  background: #fff;
  box-shadow: 0 4px 16px -4px rgba(15, 23, 42, 0.12), 0 2px 8px -2px rgba(15, 23, 42, 0.06);
  overflow: auto;
  margin-top: 0.5rem;
}

.entry-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 13px;
}

.entry-table thead {
  position: sticky;
  top: 0;
  z-index: 40;
}

.entry-table thead th {
  background: linear-gradient(135deg, #f8fafc, #f1f5f9);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #475569;
  border-bottom: 1px solid #e2e8f0;
  padding: 0.55rem 0.6rem;
  text-align: left;
}

.entry-table.fancy thead th {
  background: linear-gradient(135deg, #f8fafc, #f1f5f9);
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-bottom: 2px solid #e2e8f0;
}

.entry-table.fancy tbody tr {
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.entry-table tbody td {
  background: #fff;
  padding: 0.55rem 0.6rem;
  text-align: left;
  border-bottom: 1px solid #f1f5f9;
}

.entry-table tbody tr:hover {
  background: #f8fafc;
}

.entry-table tfoot td {
  background: #fafafa;
  font-weight: 600;
  padding: 0.65rem 0.6rem;
  border-top: 1px solid #e2e8f0;
}

.type-cell {
  font-weight: 600;
  color: #475569;
}

.strong {
  font-weight: 600;
  color: #0f172a;
}

.category-cell {
  font-weight: 500;
  color: #6b7280;
  background-color: #f3f4f6;
  padding: 0.4rem 0.6rem;
  border-radius: 4px;
}

.spec-cell {
  max-width: 160px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: #475569;
}

.fee-mode {
  font-weight: 600;
  color: #2563eb;
}

.fee-amount {
  font-weight: 600;
  color: #059669;
}

.qty {
  font-weight: 600;
  color: #475569;
  text-align: center;
}

.line-cost {
  font-weight: 600;
  color: #1e40af;
  text-align: right;
}

.actions {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
  width: 70px;
}

.qty-input {
  width: 52px;
  padding: 0.3rem 0.4rem;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  font-size: 12px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  background: #fff;
  transition: all 0.2s;
}

.qty-input:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25);
  background: #f8fbff;
}

.link-btn {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  color: #2563eb;
  position: relative;
}

.link-btn:hover {
  color: #1d4ed8;
  text-decoration: underline;
}

.link-btn.danger {
  color: #dc2626;
}

.link-btn.danger:hover {
  color: #b91c1c;
}

.tar {
  text-align: right;
}

.btn {
  cursor: pointer;
  border: 1px solid transparent;
  padding: 0.6rem 1.1rem;
  border-radius: 12px;
  font-size: 14px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  transition: all 0.3s;
}

.btn.primary {
  background: linear-gradient(135deg, #3b82f6, #2563eb);
  color: #fff;
  border-color: #2563eb;
}

.btn.primary:hover {
  background: linear-gradient(135deg, #2563eb, #1d4ed8);
  transform: translateY(-2px);
}

.btn.secondary {
  background: #ffffff;
  border: 1px solid #d1d5db;
  color: #374151;
}

.btn.secondary:hover {
  background: #f8fafc;
  border-color: #cbd5e1;
  transform: translateY(-2px);
}

.btn.sm {
  padding: 0.35rem 0.65rem;
  font-size: 12px;
}

.btn.link {
  background: transparent;
  border: none;
  color: #2563eb;
  padding: 0.25rem 0.5rem;
}

.btn.link:hover {
  text-decoration: underline;
}

.btn.link.danger {
  color: #dc2626;
}

.empty-hint {
  color: #94a3b8;
  font-size: 13px;
  text-align: center;
  padding: 2rem;
  font-style: italic;
}

.dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.8rem;
  padding: 0.75rem 1.3rem 0.9rem;
  border-top: 1px solid #e2e8f0;
  background: linear-gradient(135deg, #ffffff, #f8fafc);
}
</style>
